package com.yellow.cloud.gateway.filter;

import com.alibaba.fastjson.JSON;
import com.yellow.cloud.gateway.service.AuthService;
import com.yellowframework.cloud.common.autoconfigure.CommonProperties;
import com.yellowframework.cloud.common.model.response.CommonCode;
import com.yellowframework.cloud.common.model.response.ResponseResult;
import com.yellowframework.cloud.common.model.response.ResultCode;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.Collections;

/**
 * 身份校验过虑器
 * @author Administrator
 * @version 1.0
 **/

@Component
public class LoginFilter implements GlobalFilter, Ordered {

    @Autowired
    private AuthService authService;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //获取rawPath路径
        String rawPath = exchange.getRequest().getURI().getRawPath();

        for (String path : CommonProperties.path.getAnon()) {
            if (rawPath.contains(path)) {
                return chain.filter(exchange);
            }
        }

        //得到request
        final ServerHttpRequest request = exchange.getRequest();

        // 取cookie中的身份令牌
        String tokenFromCookie = authService.getTokenFromCookie(request);
        if(StringUtils.isEmpty(tokenFromCookie)){
            return access_denied(exchange, CommonCode.UNAUTHENTICATED);
        }

        //从header中取jwt
        String jwtFromHeader = authService.getJwtFromHeader(request);
        if(StringUtils.isEmpty(jwtFromHeader)){
            return access_denied(exchange, CommonCode.UNAUTHENTICATED);
        }

        //从redis取出jwt的过期时间
        long expire = authService.getExpire(tokenFromCookie);
        if(expire<0){
            return access_denied(exchange, CommonCode.UNAUTHENTICATED);
        }

        // 校验token
        if(authService.invalid(tokenFromCookie, jwtFromHeader)){
            return access_denied(exchange, CommonCode.UNAUTHENTICATED);
        }

        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }

    /**
     * 未认证
     * */
    private Mono<Void> access_denied(ServerWebExchange exchange, ResultCode resultCode) {
        byte[] bytes = JSON.toJSONString(ResponseResult.get(resultCode)).getBytes(StandardCharsets.UTF_8);
        DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(bytes);
        exchange.getResponse().setStatusCode(HttpStatus.OK);
        exchange.getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON);
        exchange.getResponse().getHeaders().setAccessControlAllowOrigin("*");
        exchange.getResponse().getHeaders().setAcceptCharset(Collections.singletonList(StandardCharsets.UTF_8));
        return exchange.getResponse().writeWith(Flux.just(buffer));
    }
}
